home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / contrib / cfemacs.el < prev    next >
Encoding:
Text File  |  1997-12-05  |  11.7 KB  |  360 lines

  1. ;;; cfengine.el --- An Emacs major-mode for editing cfengine scripts
  2. ;;; Copyright (C) 1997 Rolf Ebert
  3.  
  4. ;;; Authors: Rolf Ebert      <ebert@waporo.muc.de>
  5. ;;; Keywords: languages 
  6. ;;; Rolf Ebert's version: cfengine.el-V1_1
  7.  
  8. ;;; This file is not part of GNU Emacs or XEmacs.
  9.  
  10. ;; cfengine.el is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14.  
  15. ;; cfengine.el is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;; GNU General Public License for more details.
  19.  
  20. ;; You should have received a copy of the GNU General Public License
  21. ;; along with cfengine; see the file COPYING.  If not, write to the
  22. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  23. ;; Boston, MA 02111-1307, USA.
  24.  
  25. ;; USAGE:
  26.  
  27. ;; I have the following lines in my .emacs
  28.  
  29. ;;  ; autoload when needed
  30. ;;  (autoload 'cfengine-mode "cfengine" "" t nil)
  31.  
  32. ;;  ; start colour highlighting
  33. ;;  ; if GNU Emacs >= 19.31
  34. ;;  ;   (global-font-lock-mode t)
  35. ;;  ; if XEmacs
  36. ;;  (add-hook 'cfengine-mode-hook 'turn-on-font-lock)
  37.  
  38. ;;  ; detect file type by name (cf.*)
  39. ;;  (setq auto-mode-alist (append '(("cf\\." . cfengine-mode))
  40. ;;                                auto-mode-alist))
  41.  
  42.  
  43.  
  44. (defvar cfengine-indent 3
  45.   "*Defines the size of Cfengine indentation.")
  46.  
  47. (defvar cfengine-mode-abbrev-table nil
  48.   "Abbrev table used in Cfengine mode.")
  49. (define-abbrev-table 'cfengine-mode-abbrev-table ())
  50.  
  51. (defvar cfengine-mode-map ()
  52.   "Local keymap used for Cfengine mode.")
  53.  
  54. (defvar cfengine-mode-syntax-table nil
  55.   "Syntax table to be used for editing Cfengine source code.")
  56.  
  57. (defvar cfengine-mode-hook nil
  58.   "*List of functions to call when Cfengine mode is invoked.
  59. This is a good place to add specific bindings.")
  60.  
  61.  
  62. ;;;-------------
  63. ;;;  functions
  64. ;;;-------------
  65.  
  66. (defun cfengine-xemacs ()
  67.   (or (string-match "Lucid"  emacs-version)
  68.       (string-match "XEmacs" emacs-version)))
  69.  
  70. (defun cfengine-create-syntax-table ()
  71.   "Create the syntax table for Cfengine mode."
  72.   (setq cfengine-mode-syntax-table (make-syntax-table (standard-syntax-table)))
  73.   (set-syntax-table cfengine-mode-syntax-table)
  74.  
  75.   ;; string
  76.   ;(modify-syntax-entry ?\" "\"" cfengine-mode-syntax-table)
  77.   ;(modify-syntax-entry ?\' "\"" cfengine-mode-syntax-table)
  78.   ;(modify-syntax-entry ?\` "\"" cfengine-mode-syntax-table)
  79.   (modify-syntax-entry ?\" "." cfengine-mode-syntax-table)
  80.   (modify-syntax-entry ?\' "." cfengine-mode-syntax-table)
  81.   (modify-syntax-entry ?\` "." cfengine-mode-syntax-table)
  82.  
  83.   ;; comment
  84.   (modify-syntax-entry ?#  "<"  cfengine-mode-syntax-table)
  85.   (modify-syntax-entry ?\f  ">" cfengine-mode-syntax-table)
  86.   (modify-syntax-entry ?\n  ">" cfengine-mode-syntax-table)
  87.  
  88.   (modify-syntax-entry ?%  "."  cfengine-mode-syntax-table)
  89.   (modify-syntax-entry ?:  "."  cfengine-mode-syntax-table)
  90.   (modify-syntax-entry ?\; "."  cfengine-mode-syntax-table)
  91.   (modify-syntax-entry ?&  "."  cfengine-mode-syntax-table)
  92.   (modify-syntax-entry ?\|  "." cfengine-mode-syntax-table)
  93.   (modify-syntax-entry ?+  "."  cfengine-mode-syntax-table)
  94.   (modify-syntax-entry ?*  "." cfengine-mode-syntax-table)
  95.   (modify-syntax-entry ?/  "." cfengine-mode-syntax-table)
  96.   (modify-syntax-entry ?=  "." cfengine-mode-syntax-table)
  97.   (modify-syntax-entry ?<  "." cfengine-mode-syntax-table)
  98.   (modify-syntax-entry ?>  "." cfengine-mode-syntax-table)
  99.   (modify-syntax-entry ?$ "."  cfengine-mode-syntax-table)
  100.   (modify-syntax-entry ?. "."  cfengine-mode-syntax-table)
  101.   (modify-syntax-entry ?\\ "." cfengine-mode-syntax-table)
  102.   (modify-syntax-entry ?-  "." cfengine-mode-syntax-table)
  103.   ;; define what belongs in symbols
  104.   (modify-syntax-entry ?_ "_" cfengine-mode-syntax-table)
  105.   ;; define parentheses to match
  106.   (modify-syntax-entry ?\( "()" cfengine-mode-syntax-table)
  107.   (modify-syntax-entry ?\) ")(" cfengine-mode-syntax-table)
  108.   )
  109.  
  110.  
  111. ;;;###autoload
  112. (defun cfengine-mode ()
  113.   "Cfengine mode is the major mode for editing Cfengine code.
  114.  
  115. Bindings are as follows:
  116.  
  117.  Indent line                                          '\\[cfengine-tab]'
  118.  Indent line, insert newline and indent the new line. '\\[newline-and-indent]'
  119.  
  120. Comments are handled using standard Emacs conventions, including:
  121.  Start a comment                                      '\\[indent-for-comment]'
  122.  Comment region                                       '\\[comment-region]'
  123.  Uncomment region                                     '\\[cfengine-uncomment-region]'
  124.  Continue comment on next line                        '\\[indent-new-comment-line]'
  125. "
  126.  
  127.   (interactive)
  128.   (kill-all-local-variables)
  129.  
  130.   (make-local-variable 'require-final-newline)
  131.   (setq require-final-newline t)
  132.  
  133.   (make-local-variable 'comment-start)
  134.   (setq comment-start "# ")
  135.  
  136.   ;; comment end must be set because it may hold a wrong value if
  137.   ;; this buffer had been in another mode before. RE
  138.   (make-local-variable 'comment-end)
  139.   (setq comment-end "")
  140.  
  141.   (make-local-variable 'comment-start-skip) ;; used by autofill
  142.   (setq comment-start-skip "#+[ \t]*")
  143.  
  144.   (make-local-variable 'indent-line-function)
  145.   (setq indent-line-function 'cfengine-indent-current-function)
  146.  
  147.   (make-local-variable 'fill-column)
  148.   (setq fill-column 75)
  149.  
  150.   (make-local-variable 'comment-column)
  151.   (setq comment-column 40)
  152.  
  153.   (make-local-variable 'parse-sexp-ignore-comments)
  154.   (setq parse-sexp-ignore-comments t)
  155.  
  156.   (make-local-variable 'case-fold-search)
  157.   (setq case-fold-search t)
  158.  
  159.   (make-local-variable 'outline-regexp)
  160.   (setq outline-regexp "[^\n\^M]")
  161.   (make-local-variable 'outline-level)
  162.   (setq outline-level 'cfengine-outline-level)
  163.  
  164.   (make-local-variable 'fill-paragraph-function)
  165.   (setq fill-paragraph-function 'cfengine-fill-comment-paragraph)
  166.   ;;(make-local-variable 'adaptive-fill-regexp)
  167.  
  168.   (if (cfengine-xemacs) nil ; XEmacs uses properties 
  169.     (make-local-variable 'font-lock-defaults)
  170.     (setq font-lock-defaults
  171.           '((cfengine-font-lock-keywords
  172.              cfengine-font-lock-keywords-1 cfengine-font-lock-keywords-2)
  173.             nil t
  174.             ((?\_ . "w"))
  175.             beginning-of-line
  176.             )))
  177.  
  178.   (setq major-mode 'cfengine-mode)
  179.   (setq mode-name "Cfengine")
  180.  
  181.   (use-local-map cfengine-mode-map)
  182.  
  183.   (if cfengine-mode-syntax-table
  184.       (set-syntax-table cfengine-mode-syntax-table)
  185.     (cfengine-create-syntax-table))
  186.  
  187.   ;; add menu 'Cfengine' to the menu bar
  188.   ;  (cfengine-add-cfengine-menu)
  189.  
  190.   (run-hooks 'cfengine-mode-hook))
  191.  
  192.  
  193. ;;;----------------------;;;
  194. ;;; Behaviour Of TAB Key ;;;
  195. ;;;----------------------;;;
  196.  
  197. (defun cfengine-tab ()
  198.   "Do indenting or tabbing according to `cfengine-tab-policy'."
  199.   (interactive)
  200.   (cond (1 (cfengine-tab-hard))
  201.         ((eq cfengine-tab-policy 'indent-auto) (cfengine-indent-current))
  202.         ))
  203.  
  204. (defun cfengine-untab ()
  205.   "Do dedenting or detabbing."
  206.   (interactive)
  207.   (cfengine-untab-hard))
  208.  
  209.  
  210. (defun cfengine-indent-current-function ()
  211.   "Cfengine mode version of the indent-line-function."
  212.   (interactive "*")
  213.   (let ((starting-point (point-marker)))
  214.     (cfengine-beginning-of-line)
  215.     (cfengine-tab)
  216.     (if (< (point) starting-point)
  217.         (goto-char starting-point))
  218.     (set-marker starting-point nil)
  219.     ))
  220.  
  221.  
  222. (defun cfengine-tab-hard ()
  223.   "Indent current line to next tab stop."
  224.   (interactive)
  225.   (save-excursion
  226.     (beginning-of-line)
  227.     (insert-char ?  cfengine-indent))
  228.   (if (save-excursion (= (point) (progn (beginning-of-line) (point))))
  229.       (forward-char cfengine-indent)))
  230.  
  231.  
  232. (defun cfengine-untab-hard ()
  233.   "indent current line to previous tab stop."
  234.   (interactive)
  235.   (let  ((bol (save-excursion (progn (beginning-of-line) (point))))
  236.         (eol (save-excursion (progn (end-of-line) (point)))))
  237.     (indent-rigidly bol eol  (- 0 cfengine-indent))))
  238.  
  239.  
  240.  
  241. ;;;---------------;;;
  242. ;;; Miscellaneous ;;;
  243. ;;;---------------;;;
  244.  
  245. (defun cfengine-uncomment-region (beg end)
  246.   "delete `comment-start' at the beginning of a line in the region."
  247.   (interactive "r")
  248.   (comment-region beg end -1))
  249.  
  250.  
  251.  
  252. ;;;-----------------------
  253. ;;; define keymap for Cfengine
  254. ;;;-----------------------
  255.  
  256. (if (not cfengine-mode-map)
  257.     (progn
  258.       (setq cfengine-mode-map (make-sparse-keymap))
  259.  
  260.       ;; Indentation and Formatting
  261.       (define-key cfengine-mode-map "\C-j"     'cfengine-indent-newline-indent)
  262.       (define-key cfengine-mode-map "\t"       'cfengine-tab)
  263.       (if (cfengine-xemacs)
  264.       (define-key cfengine-mode-map '(shift tab)    'cfengine-untab)
  265.     (define-key cfengine-mode-map [S-tab]    'cfengine-untab))
  266. ;      (define-key cfengine-mode-map "\M-\C-e"  'cfengine-next-procedure)
  267. ;      (define-key cfengine-mode-map "\M-\C-a"  'cfengine-previous-procedure)
  268. ;      (define-key cfengine-mode-map "\C-c\C-a" 'cfengine-move-to-start)
  269. ;      (define-key cfengine-mode-map "\C-c\C-e" 'cfengine-move-to-end)
  270.  
  271.  
  272.       (define-key cfengine-mode-map "\177"     'backward-delete-char-untabify)
  273.  
  274.       ;; Use predefined function of emacs19 for comments (RE)
  275.       (define-key cfengine-mode-map "\C-c;"    'comment-region)
  276.       (define-key cfengine-mode-map "\C-c:"    'cfengine-uncomment-region)
  277.  
  278.       ))
  279.  
  280.  
  281. ;;;-------------------
  282. ;;; define menu 'Cfengine'
  283. ;;;-------------------
  284.  
  285. (require 'easymenu)
  286.  
  287. (defun cfengine-add-cfengine-menu ()
  288.   "Adds the menu 'Cfengine' to the menu bar in Cfengine mode."
  289.   (easy-menu-define cfengine-mode-menu cfengine-mode-map "Menu keymap for Cfengine mode."
  290.                     '("Cfengine"
  291. ;                      ["Next Package" cfengine-next-package t]
  292. ;                      ["Previous Package" cfengine-previous-package t]
  293. ;                      ["Next Procedure" cfengine-next-procedure t]
  294. ;                      ["Previous Procedure" cfengine-previous-procedure t]
  295. ;                      ["Goto Start" cfengine-move-to-start t]
  296. ;                      ["Goto End" cfengine-move-to-end t]
  297. ;                      ["------------------" nil nil]
  298.                       ["Indent Current Line (TAB)"
  299.                        cfengine-indent-current-function t]
  300.                       ))
  301.   (if (cfengine-xemacs)
  302.       (progn
  303.         (easy-menu-add cfengine-mode-menu)
  304.         (setq mode-popup-menu (cons "Cfengine mode" cfengine-mode-menu)))))
  305.  
  306.  
  307.  
  308. ;;;---------------------------------------------------
  309. ;;; support for font-lock
  310. ;;;---------------------------------------------------
  311.  
  312. (defconst cfengine-font-lock-keywords-1
  313.   (list
  314.    ;; actions
  315.    (list "^[ \t]*\\([a-zA-Z0-9]+\\):[^:]" '(1 font-lock-keyword-face) )
  316.    )
  317.   "Subdued level highlighting for Cfengine mode.")
  318.  
  319. (defconst cfengine-font-lock-keywords-2
  320.   (append cfengine-font-lock-keywords-1
  321.    (list
  322.     ;;
  323.     ;; classes = alphanum or ().|!
  324.     '("^[ \t]*\\([a-zA-Z0-9_\\(\\)\\.\\|\\!]+\\)::" (1 font-lock-function-name-face))
  325.     ;;
  326.     ;; variables
  327.     '("$(\\([a-zA-Z0-9_]+\\))" (1 font-lock-variable-name-face))
  328.     ))
  329.   "Gaudy level highlighting for Cfengine mode.")
  330.  
  331. (defvar cfengine-font-lock-keywords cfengine-font-lock-keywords-2
  332.   "Default expressions to highlight in Cfengine mode.")
  333.  
  334.  
  335. ;; set font-lock properties for XEmacs
  336. (if (cfengine-xemacs)
  337.     (put 'cfengine-mode 'font-lock-defaults
  338.          '(cfengine-font-lock-keywords
  339.            nil t ((?\_ . "w")) beginning-of-line)))
  340.  
  341. ;;;
  342. ;;; support for outline
  343. ;;;
  344.  
  345. ;; used by outline-minor-mode
  346. (defun cfengine-outline-level ()
  347.   (save-excursion
  348.     (skip-chars-forward "\t ")
  349.     (current-column)))
  350.  
  351.  
  352. ;;; provide ourself
  353.  
  354. (provide 'cfengine-mode)
  355.  
  356. ;;; cfengine.el ends here
  357.  
  358.  
  359.  
  360.